import React from "react";
import echarts from 'echarts';
import { reduceConfig2 } from '@easyv/utils/lib/common/reduce-config';

const DataType = {
    Array: 1,
    Object: 2,
    Number: 3,
    DataSet: 4
}

export default class EChartsComponent extends React.Component {
    constructor(props) {
        super(props);
        this.refresh(props);
        this.chartContainer = React.createRef();
        this.staticOptions = {};
        this.options = {};
        this.dataAxis = null;
    }

    setOption(option) {
        transformAxisArray(option);
        this.dataType = this.getDataType(option);

        //获取轴数据
        for (const k of ["xAxis", "yAxis", "singleAxis", "radiusAxis", "angleAxis"]) {
            if (option[k] && option[k].data) {
                this.dataAxis = option[k];
            }
        }
        this.options = option;
    }

    getDataType(options) {
        if (options.dataset) {
            return DataType.DataSet;
        }
        let firstData;
        try {
            firstData = options.series[0].data[0];
        } catch (e) { //任意一步报错都无需转换，直接结束
            return null;
        }

        const dataType = typeof firstData;
        if (dataType == "number" || !isNaN(parseFloat(firstData))) { //数字元素
            return DataType.Number;
        } else if (dataType == "object") {
            if (Array.isArray(firstData)) { //数组元素
                return DataType.Array;
            } else { //对象元素
                return DataType.Object;
            }
        }
    }

    refresh(props) {
        this.config = reduceConfig2(props.configuration);
    }

    componentWillReceiveProps(props) {
        this.refresh(props);
    }

    render() {
        const { id } = this.props;
        const {
            chart: {
                dimension: {
                    chartPosition,
                    chartDimension: { width, height },
                }
            },
        } = this.config;

        return (<div
            id={id}
            className='__easyv-component'
            style={{
                position: 'absolute',
                ...chartPosition,
                width,
                height
            }}
            ref={e => this.chartContainer.current = e}
        ></div>);
    }

    initECharts() {
        const eCharts = echarts.init(this.chartContainer.current);
        this.mergeConfig(this.config.chart);
        this.appendDataToOptions(this.options);
        console.log(this.options);
        eCharts.setOption(this.options);
        eCharts.resize();
    }

    componentDidMount() {
        this.initECharts();
    }

    componentDidUpdate() {
        this.initECharts();
    }

    appendDataToOptions(options) {
        const data = this.props.data;
        const sMap = {};
        if (this.dataType == DataType.DataSet) {
            options.dataset = deepCopy(data);
            return;
        } else if (this.dataType == DataType.Number) {
            const xMap = {};
            data.forEach(e => {
                xMap[e.x] = true;

                const s = e.s || "__single__";
                if (!sMap[s]) {
                    sMap[s] = [];
                }

                sMap[s].push(e.y);
            });

            //注入轴数据
            if (this.dataAxis) {
                this.dataAxis.data = Object.keys(xMap);
            }
        } else if (this.dataType == DataType.Array) {
            //转化
            data.forEach(e => {
                const s = e.s || "__single__";
                if (!sMap[s]) {
                    sMap[s] = [];
                }

                sMap[s].push(e.y);
            });
        } else {
            //转化
            data.forEach(e => {
                const s = e.s || "__single__";
                if (!sMap[s]) {
                    sMap[s] = [];
                }

                sMap[s].push(e);
            });
        }

        //注入系列数据
        if (options.series.length <= 1 && sMap.__single__) {
            options.series[0].data = sMap.__single__;
        } else {
            options.series.forEach(e => {
                if (sMap[e.name]) {
                    e.data = sMap[e.name];
                }
            });
        }

        //注入图例数据
        if (options.legend && options.legend.data) {
            options.legend.data = Object.keys(sMap);
        }
    }

    mergeConfig(configChart) {
        function recurve(source, target) {
            for (let k in target) {
                const v = target[k];
                if (typeof v == "object") {
                    if (Array.isArray(v)) {
                        source[k] = Object.values(source[k]);
                    } else {
                        recurve(v);
                    }
                }
            }
        }
        recurve(configChart, this.options);

        mergeObject(configChart, this.options);
    }

    mergeSeries(configChart) {
        try {
            this.options.series = configChart.series;
        } catch (e) {
            console.log(e);
        }
    }
}

function transformAxisArray(obj) {
    function func(o, k) {
        const v = o[k];
        if (v && Array.isArray(v) && v.length == 1) {
            o[k] = v[0];
        }
    }
    func(obj, "singleAxis");
    func(obj, "xAxis");
    func(obj, "yAxis");
}

function mergeObject(source, target) {
    if (typeof source != "object" || typeof target != "object") {
        return;
    }

    for (let k in source) {
        const v = source[k];
        const type = typeof v;
        if (type == "object") {
            if (target[k] == void 0) {
                target[k] = {};
            }
            mergeObject(v, target[k]);
        } else if (k != "series") {
            target[k] = v;
        }
    }
}

function deepCopy(obj) {
    if (typeof obj == "object") {
        const o = Array.isArray(obj) ? [] : {};
        for (const k in obj) {
            if (Object.getOwnPropertyNames(k)) { //JS特性，可以无视这一句
                o[k] = deepCopy(obj[k]);
            }
        }
        return o;
    } else {
        return obj;
    }
}